package com.basic.library.base;


import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.graphics.Color;
import android.os.Build;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.FrameLayout;
import android.widget.TextView;

import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import androidx.databinding.DataBindingUtil;
import androidx.databinding.ViewDataBinding;
import androidx.fragment.app.FragmentActivity;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModel;
import androidx.lifecycle.ViewModelProviders;

import com.basic.library.Interface.BusCallback;
import com.basic.library.R;
import com.basic.library.base.BaseViewModel.ParameterField;
import com.basic.library.binding.command.BindingCommand;
import com.basic.library.httpmanager.task.IView;
import com.basic.library.httpmanager.task.LView;
import com.basic.library.httpmanager.task.LViewEnum;
import com.basic.library.utils.FlymeStatusbarColorUtils;
import com.basic.library.utils.ScreenUtils;
import com.basic.library.utils.SystemBarTintManager;
import com.jeremyliao.liveeventbus.LiveEventBus;
import com.maning.mndialoglibrary.MProgressDialog;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Map;
import java.util.Objects;

import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.disposables.Disposable;


public abstract class BaseActivity<V extends ViewDataBinding, VM extends BaseViewModel> extends NoDoubleClickActivity implements IView, LView {
    protected V binding;
    protected VM viewModel;
    private int viewModelId;
    protected FragmentActivity activity;
    protected boolean statusBarTextColorBlack = false; //状态栏字体颜色 变化标志  true黑色。反之白色

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setStatusBarTrans();
        initSCREEN_ORIENTATION();
//        overridePendingTransition(R.anim.slide_in_from_right, R.anim.slide_out_to_left);
        activity = this;
        //私有的初始化Databinding和ViewModel方法
        initViewDataBinding(savedInstanceState);
        registorUIChangeLiveDataCallBack();
        initView();
        initLiveDataBus();
    }

    @Override
    protected void onPostCreate(@Nullable Bundle savedInstanceState) {
        super.onPostCreate(savedInstanceState);
        bindingOver();
        viewModel.bindingOver();
    }

    /**
     * 6.0以后，可设状态栏字体颜色，所以可以使状态栏全透明，但是5.0的系统，无法控制字体颜色，所以，要给状态栏加个蒙版保个险
     * ps:SYSTEM_UI_FLAG_LIGHT_STATUS_BAR 在起始页设置的话，8.0的刘海机子statusbar会闪一下
     */
    protected boolean needFullScreen = false;

    protected void setStatusBarTrans() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && Build.VERSION.SDK_INT < 23) {//6.0以下系统
            if (!ScreenUtils.MIUISetStatusBarLightMode(getWindow(), true)) {//小米的用自己的方法，不成功的话，再加个遮罩
                // 创建状态栏的管理实例
                SystemBarTintManager tintManager = new SystemBarTintManager(this);
                // 激活状态栏设置
                tintManager.setStatusBarTintEnabled(true);
                // 设置一个颜色给系统栏
                tintManager.setTintColor(getResources().getColor(R.color.statusbar_color));
            }
        } else if (Build.VERSION.SDK_INT >= 23) { //下面方法设置了以后，style里的沉浸式其实已经没有用了。
            Window window = getWindow();
            window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS | WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
            if (statusBarTextColorBlack) {
                if (needFullScreen) {
                    window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                            | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                            | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
                } else {
                    window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                            | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
                }
                FlymeStatusbarColorUtils.setStatusBarDarkIcon(this, true);
                ScreenUtils.MIUISetStatusBarLightMode(getWindow(), statusBarTextColorBlack);
            } else {
                if (needFullScreen) {
                    window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                            | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                            | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
                } else {
                    window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                            | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
                }
            }
            window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
            window.setStatusBarColor(Color.TRANSPARENT);
        }
    }

    /**
     * 初始化ViewModel的id
     *
     * @return BR的id
     */
    public abstract int initVariableId();

    /**
     * 初始化ViewModel
     *
     * @return 继承BaseViewModel的ViewModel
     */
    public VM initViewModel() {
        return null;
    }

    public abstract int getContentViewResId();

    protected abstract void initView();

    protected void bindingOver() {
    }

    protected void initSCREEN_ORIENTATION() {
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
    }

    //开启LiveDataBus消息总线
    public BusCallback openLiveDataBus() {
        return null;
    }

    //初始化LiveDataBus消息总线
    @SuppressWarnings("unchecked")
    protected void initLiveDataBus() {
        BusCallback busCallback = openLiveDataBus();
        if (busCallback != null) {
            if (busCallback.key != null)
                for (String s : busCallback.key) {
                    String key0 = s != null ? s : getClass().getName();
                    LiveEventBus.get(key0)
                            .observe(this, new Observer<Object>() {
                                @Override
                                public void onChanged(Object o) {
//                                    Out.p(o.getClass() + "--" + busCallback.mType);
                                    //过滤类型不一致的, / 类型为Object时直接放行
                                    try {
                                        if (busCallback.mType == o.getClass()
                                                || busCallback.mType == Object.class
                                                || busCallback.mType.toString().startsWith(Objects.requireNonNull(o.getClass().getCanonicalName())))

                                            busCallback.onBusChanged(o);
                                    } catch (Exception e) {
                                        e.printStackTrace();
                                    }
                                }
                            });
                }
        }
    }

    protected void onStop() {
        super.onStop();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
    }

    // 设置标题
    protected void setTitle(String title) {
        viewModel.title.set(title);
    }

    // 设置右侧textview
    protected void setRight(int imageId, int drawableTint, int textColor, String text, BindingCommand bindingCommand) {
        viewModel.title_right.set(text);
        viewModel.drawable_right.set(imageId);
        if (drawableTint != 0) {
            viewModel.drawable_rightTint.set(drawableTint);
        }
        if (textColor != 0) {
            viewModel.drawable_rightTextColor.set(ConstKt.getColor(textColor));
        }
        viewModel.onclick_right.set(bindingCommand);
    }

    // 设置右侧textview
    public void setEnd(int imageId, int drawableTint, BindingCommand bindingCommand) {
        viewModel.drawable_end.set(imageId);
        if (drawableTint != 0)
            viewModel.drawable_endTint.set(ContextCompat.getColor(this, drawableTint));
        viewModel.onclick_end.set(bindingCommand);
    }

    public void setBack(BindingCommand bindingCommand) {// 返回
        if (bindingCommand != null)
            viewModel.onclick_back.set(bindingCommand);
        else
            viewModel.onclick_back.set(new BindingCommand(this::finish));
    }

    @Override
    public void finish() {
        super.finish();
        //解除ViewModel生命周期感应
        viewModel.onFinish();
        getLifecycle().removeObserver(viewModel);
        BaseApplication.getInstance().removeActivity(this);
        compositeDisposable.clear();
        if (binding != null) {
            binding.unbind();
        }
//        overridePendingTransition(R.anim.slide_in_from_left, R.anim.slide_out_to_right);
    }

    protected CompositeDisposable compositeDisposable = new CompositeDisposable();

    /**
     * 注入绑定
     */
    private void initViewDataBinding(Bundle savedInstanceState) {
        //DataBindingUtil类需要在project的build中配置 dataBinding {enabled true }, 同步后会自动关联android.databinding包
        binding = DataBindingUtil.setContentView(this, getContentViewResId());
        viewModelId = initVariableId();
        viewModel = initViewModel();
        if (viewModel == null) {
            Class modelClass;
            Type type = getClass().getGenericSuperclass();
            if (type instanceof ParameterizedType) {
                modelClass = (Class) ((ParameterizedType) type).getActualTypeArguments()[1];
            } else {
                //如果没有指定泛型参数，则默认使用BaseViewModel
                modelClass = BaseViewModel.class;
            }
            viewModel = (VM) createViewModel(this, modelClass);
        }
        //关联ViewModel
        binding.setVariable(viewModelId, viewModel);
        //让ViewModel拥有View的生命周期感应
        getLifecycle().addObserver(viewModel);
        //注入RxLifecycle生命周期
        viewModel.injectLifecycleActivityProvider(this);
        viewModel.setIView(this);
        viewModel.setLView(this);
        binding.setLifecycleOwner(this);
    }

    //刷新布局
    public void refreshLayout() {
        if (viewModel != null) {
            binding.setVariable(viewModelId, viewModel);
        }
    }


    /**
     * =====================================================================
     **/
    //注册ViewModel与View的契约UI回调事件
    private void registorUIChangeLiveDataCallBack() {
        //加载对话框显示
        viewModel.getUC().getShowDialogEvent().observe(this, this::showProgressDialog);
        //加载对话框消失
        viewModel.getUC().getDismissDialogEvent().observe(this, v -> dismissProgressDialog());
        //跳入新页面
        viewModel.getUC().getStartActivityEvent().observe(this, params -> {
            Class<?> clz = (Class<?>) params.get(ParameterField.CLASS);
            Bundle bundle = (Bundle) params.get(ParameterField.BUNDLE);
            startActivity(clz, bundle);
        });
        //跳入ContainerActivity
        viewModel.getUC().getStartContainerActivityEvent().observe(this, params -> {
            String canonicalName = (String) params.get(ParameterField.CANONICAL_NAME);
            Bundle bundle = (Bundle) params.get(ParameterField.BUNDLE);
            startContainerActivity(canonicalName, bundle);
        });
        //关闭界面
        viewModel.getUC().getFinishEvent().observe(this, v -> finish());
        //关闭上一层
        viewModel.getUC().getOnBackPressedEvent().observe(this, v -> onBackPressed());
        viewModel.getUC().getDisposableEvent().observe(this, this::onSubscribe);
        viewModel.getUC().getAllEvent().observe(this, integerObjectMap -> {
            if (integerObjectMap != null && integerObjectMap.size() == 1) {
                for (Map.Entry<Integer, Object> entry : integerObjectMap.entrySet()) {
                    observe(entry.getKey(), entry.getValue());
                }
            } else {
                observe(-1, null);
            }
        });
    }

    public void observe(int type, Object o) {

    }

    //默认进度框，可重写
    public void showProgressDialog(String title) {
        if (!MProgressDialog.isShowing())
            MProgressDialog.showProgress(activity, title);
    }

    public void dismissProgressDialog() {
        MProgressDialog.dismissProgress();
    }

    /**
     * 跳转页面
     *
     * @param clz 所跳转的目的Activity类
     */
    public void startActivity(Class<?> clz) {
        startActivity(new Intent(this, clz));
    }

    /**
     * 跳转页面
     *
     * @param clz    所跳转的目的Activity类
     * @param bundle 跳转所携带的信息
     */
    public void startActivity(Class<?> clz, Bundle bundle) {
        Intent intent = new Intent(this, clz);
        if (bundle != null) {
            intent.putExtras(bundle);
        }
        startActivity(intent);
    }

    /**
     * 跳转容器页面
     *
     * @param canonicalName 规范名 : Fragment.class.getCanonicalName()
     */
    public void startContainerActivity(String canonicalName) {
        startContainerActivity(canonicalName, null);
    }

    /**
     * 跳转容器页面
     *
     * @param canonicalName 规范名 : Fragment.class.getCanonicalName()
     * @param bundle        跳转所携带的信息
     */
    public void startContainerActivity(String canonicalName, Bundle bundle) {
        Intent intent = new Intent(this, ContainerActivity.class);
        intent.putExtra(ContainerActivity.FRAGMENT, canonicalName);
        if (bundle != null) {
            intent.putExtra(ContainerActivity.BUNDLE, bundle);
        }
        startActivity(intent);
    }

    /**
     * 创建ViewModel
     *
     * @param cls
     * @param <T>
     * @return
     */
    public <T extends ViewModel> T createViewModel(FragmentActivity activity, Class<T> cls) {
        return ViewModelProviders.of(activity).get(cls);
    }

    @Override
    public void loading(String tag) {
        if (!MProgressDialog.isShowing())
            MProgressDialog.showProgress(activity, ConstConfig.INSTANCE.getDConfig());
    }

    @Override
    public void dismiss(String tag) {
        MProgressDialog.dismissProgress();
    }

    @Override
    public void reLogin() {
        BaseApplication.getInstance().reLogin();
    }

    @Override
    public void onSubscribe(Disposable d) {
        compositeDisposable.add(d);
    }

    /**
     * 需要覆盖的布局中的最上面的控件的id
     * 即返回与emptyCoverView等高的控件id
     * 0 默认使用baseTitleBar的布局
     * 大于0 自定义布局id
     */
    @Override
    public int getNeedCoverId() {
        return 0;
    }

    @Override
    public boolean onInterceptTouch() {
        return true;
    }

    @Override
    public View getCoverView() {
        return null;
    }

    /**
     * 除了列表以外的，空数据时怎么显示空图
     *
     * @param enumType
     */
    @Override
    public void setEmptyCover(int enumType) {
        emptyCover(enumType);
    }

    @Override
    public String getEmptyDataText() {
        return null;
    }

    View emptyCoverView;

    public void emptyCover(int enumType) {
        int redID = getNeedCoverId();
        if (emptyCoverView == null)
            emptyCoverView = getCoverView();
        if (emptyCoverView == null) {
            emptyCoverView = View.inflate(activity, R.layout.base_emptycover, null);
        }
        ViewGroup root = findViewById(android.R.id.content);
        root.removeView(emptyCoverView);
        if (enumType == LViewEnum.DataUseful) { //有数据时，直接移除空视图就可
            return;
        }
        if (root instanceof FrameLayout && emptyCoverView != null) {
            View v = null;
            if (redID > 0) {
                v = findViewById(redID);
            } else if (redID == 0) {
                v = root.findViewWithTag("baseTitleBar");
            }
            if (v == null) return;
            root.addView(emptyCoverView);
            if (onInterceptTouch())
                emptyCoverView.setOnClickListener(this);
            int[] location = new int[2];
            v.getLocationOnScreen(location);
            FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) emptyCoverView.getLayoutParams();
            if (redID == 0)
                lp.topMargin = location[1] + v.getHeight();
            else
                lp.topMargin = location[1];
            emptyCoverView.setLayoutParams(lp);
            if (getCoverView() == null) {
                TextView ep = emptyCoverView.findViewById(R.id.tvEmpty);
                switch (enumType) {
                    case LViewEnum.Start:
                        ep.setVisibility(View.INVISIBLE);
                        break;
                    case LViewEnum.Error:
                        ep.setVisibility(View.VISIBLE);
                        ep.setText("获取数据异常");
                        break;
                    case LViewEnum.DataUseless:
                        ep.setVisibility(View.VISIBLE);
                        if (getEmptyDataText() == null)
                            ep.setText("暂无数据");
                        else
                            ep.setText(getEmptyDataText());
                        break;
                }
            }
        }
    }
}
